package com.lyf.language.learn.atsgg.reflect.sample;

import com.lyf.language.learn.atsgg.reflect.PersonalAnnotation;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @AUTHOR LYF
 * @DATE 2022/6/5
 * @VERSION 1.0
 * @DESC
 */
public class RefectionTest {
    @Test
    public void test1(){
       Person person = new Person("lyf",12);
       // 调用私有熟悉
       System.out.println(person.getName());
       person.setName("lyf update");
       // 非私有调用方法
       person.show();
    }

    @Test
    public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 获取Class（lang包下） 对象(四种方式
        Class c1 = Person.class;
        // 理解几种加载器和双亲委派模型
        Class c2 = ClassLoader.getSystemClassLoader().loadClass("com.lyf.language.learn.atsgg.reflect.sample.Person");
        Class c3 = Class.forName("com.lyf.language.learn.atsgg.reflect.sample.Person");
        Class c4 = new Person().getClass();


        // 调用构造器
        Constructor constructor = c1.getConstructor(String.class,Integer.class);
        Object o = constructor.newInstance("lyf",1);
        System.out.println(o);// 可以进行强转
        Person pLyf = (Person) o;
        pLyf.show();

        // 反射--通过对象、类加载器等方式先知道了类的一切信息（构造器、等），再通过类信息去创建对象，调用指定方法（需要贯入何种对象）
        //Field field = constructor.ge
        // 调用方法
        Field field = c1.getDeclaredField("name");
        // 设置可获取
        field.setAccessible(true);
        Object name =field.get(o);// 方法调用原来的对象参数，反过来了
        System.out.println(name);
        //field.set("name","hello");
        field.set(o,"hello");

        //
        Method method = c1.getDeclaredMethod("getName");
        // 方法的相关信息获取
        System.out.println(method.getName()+":"+
                method.getDeclaredAnnotation(PersonalAnnotation.class)+":"+
                method.getDeclaringClass());
        method.setAccessible(true);
        // 方法调用
        String oName = (String) method.invoke(o);
        System.out.println(oName);

       // PersonalAnnotation.class;
        //int.class;

    }


}
